package com.itita.ww2.core;

import java.sql.SQLException;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.Lists;
import com.itita.ww2.enums.WW2ExceptionCode;
import com.itita.ww2.game.user.UserService;
import com.itita.ww2.model.user.UserProfile;
import com.itita.ww2.utils.UserUtil;
import com.itita.ww2.utils.handler.MultiHandlerUtil;
import com.smartfoxserver.v2.annotations.MultiHandler;
import com.smartfoxserver.v2.entities.User;
import com.smartfoxserver.v2.entities.data.ISFSObject;
import com.smartfoxserver.v2.extensions.BaseClientRequestHandler;
import com.smartfoxserver.v2.extensions.SFSExtension;

@MultiHandler
public abstract class AbstractClientRequestHandler extends BaseClientRequestHandler {
	protected static final Logger logger = LoggerFactory.getLogger(AbstractClientRequestHandler.class);
	protected String cmd_prefix = "error";

	// fields
	private MultiHandlerUtil mhu;

	public AbstractClientRequestHandler() {
		mhu = new MultiHandlerUtil();
		setCommandPrefix();
		init();
		// 
		logger.info("[{}] initialized.", getClass().getSimpleName());
	}

	protected abstract void init();

	protected abstract void setCommandPrefix();

	@Override
	public void handleClientRequest(User arg0, ISFSObject arg1) {
		long startTime = System.currentTimeMillis();
		String requestId = arg1.getUtfString(SFSExtension.MULTIHANDLER_REQUEST_ID);
		if (requestId == null || (requestId != null && requestId.isEmpty())) {
			return;
		}
		String fullCMD = cmd_prefix + "." + requestId;
		// init
		mhu.init(this, requestId, getInitData().toArray());
		// Execute
		try {
			mhu.execute(requestId, cmd_prefix + "." + requestId, arg0, arg1);
		} catch (WW2Exception e) {
			MessageHandler.getInstance().sendMsg(fullCMD, e.getRetObj(), arg0, e.getExCode(), false);
			logger.error("ERROR: [uid: {} | id:{} | playerId: {}] msg:{}",
					arg0.containsProperty("uid") ? arg0.getProperty("uid") : "-1", arg0.getSession().getId(),
					arg0.getPlayerId(), e.toString());
			// e.printStackTrace();
		} catch (SQLException e) {
			MessageHandler.getInstance().sendMsg(fullCMD, null, arg0, WW2ExceptionCode.SQLEXCEPTION, false);
			logger.error("ERROR: [uid: {} | id:{} | playerId: {}] msg:{}",
					arg0.containsProperty("uid") ? arg0.getProperty("uid") : "-1", arg0.getSession().getId(),
					arg0.getPlayerId(), e.toString());
			e.printStackTrace();
		}
		long endTime = System.currentTimeMillis();
		long costTime = endTime - startTime;
		// 

		if (UserUtil.isGuest(arg0)) {
			logger.info("[Guest: id:{} | playerId:{}] | {} | {}ms", arg0.getSession().getId(), arg0.getPlayerId(),
					fullCMD, costTime);
		} else {
			UserProfile userProfile = UserService.getInstance().getUserProfile(arg0);
			if (userProfile == null) {
				logger.error("[id:{} | playerId:{} | uid:{}] userProfile is null!", arg0.getSession().getId(),
						arg0.getPlayerId(), arg0.getProperty("uid"));
			} else {
				// @formatter:off
				logger.info("[Name:{} id:{} playerId:{} uid:{} {}] | {} | {}ms", 
						arg0.getName(),
						arg0.getSession().getId(),
						arg0.getPlayerId(),
						userProfile.getUid(), 
						userProfile.isJoinAlliance() ? "aid:" + userProfile.getAid() : "",
						fullCMD, 
						costTime);
				// @formatter:on
			}
		}
	}

	protected List<Object> getInitData() {
		return Lists.newArrayList(ServerService.getInstance().getSFSDBManager());
	}

	protected void addClientRequestItem(String requestId, Class<?> clazz) {
		this.mhu.addClientRequestItem(requestId, clazz);
	}
}
